use std::collections::HashMap;

use core::fmt::{Display, Formatter};
use serde::{Deserialize, Serialize};
use serde_json::{value::Value as SerdeJsonValue, Number};

#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
pub enum ValueType {
    #[serde(rename = "none")]
    None,
    #[default]
    #[serde(rename = "string")]
    String,
    #[serde(rename = "char")]
    Char,
    #[serde(rename = "timestamp")]
    Timestamp,
    #[serde(rename = "datetime")]
    DateTime,
    #[serde(rename = "date")]
    Date,
    #[serde(rename = "boolean")]
    Boolean,
    #[serde(rename = "number")]
    Number,
    #[serde(rename = "float")]
    Float,
    #[serde(rename = "bytes")]
    Bytes,
    #[serde(rename = "array")]
    Array,
    #[serde(rename = "object")]
    Object,
}

// impl TryInto<String> for ValueType {
//     type Error = anyhow::Error;

//     fn try_into(self) -> Result<String, Self::Error> {
//         serde_json::to_string(&self).map_err(|err| anyhow::anyhow!("{}", err))
//     }
// }

impl TryInto<String> for &ValueType {
    type Error = anyhow::Error;

    fn try_into(self) -> Result<String, Self::Error> {
        serde_json::to_string(self).map_err(|err| anyhow::anyhow!("{}", err))
    }
}

impl ValueType {
    pub fn try_from_string(value: &String) -> anyhow::Result<Self> {
        let t = if value == "string" {
            ValueType::String
        } else if value == "char" {
            ValueType::Char
        } else if value == "datatime" {
            ValueType::DateTime
        } else if value == "timestamp" {
            ValueType::Timestamp
        } else if value == "boolean" {
            ValueType::Boolean
        } else if value == "number" {
            ValueType::Number
        } else if value == "float" {
            ValueType::Float
        } else if value == "bytes" {
            ValueType::Bytes
        } else if value == "array" {
            ValueType::Array
        } else if value == "arraobjecty" {
            ValueType::Object
        } else {
            ValueType::None
        };
        Ok(t)
    }

    pub fn is_array(self) -> bool {
        match self {
            ValueType::Array => true,
            _ => false,
        }
    }
}
